package com.gb.web.common.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.QName;


public class XmlUtil {
	private final static String XML_DECLARATION = "<?xml version=\"1.0\" encoding=\"utf-8\"?>";

	/**
	 * xml转map
	 * @param xml
	 * @return
	 */
	public static Map<String, String> xmlToMap(String xml) {
		Map<String, String> map = new HashMap<String, String>();
		Document document = null;
		try {
			document = DocumentHelper.parseText(xml);
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		if (document == null)
			return map;
		Element element = document.getRootElement();
		for (Iterator<?> iterator = element.elementIterator(); iterator.hasNext();) {
			Element e = (Element) iterator.next();
			map.put(e.getName(), e.getText());
		}
		return map;
	}

	/**
	 * map转xml字符串
	 * @param map
	 * @return
	 */
	public static String mapToXml(Map<?, ?> map) {
		StringBuffer sb = new StringBuffer(XML_DECLARATION);
		try {
			mapConvertXml(map, sb);
			return sb.toString();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * map转xml节点信息
	 * @param map
	 * @param sb
	 */
	@SuppressWarnings("rawtypes")
	public static void mapConvertXml(Map<?, ?> map, StringBuffer sb) {
		if (sb == null)
			sb = new StringBuffer();
		Set<?> set = map.keySet();
		for (Iterator<?> it = set.iterator(); it.hasNext();) {
			String key = (String) it.next();
			Object value = map.get(key);
			if (null == value)
				value = "";
			if (value.getClass().getName().equals("java.util.ArrayList")) {
				List<?> list = (List<?>) map.get(key);
				sb.append("<" + key + ">");
				for (int i = 0; i < list.size(); i++) {
					Map<?, ?> hm = (Map<?, ?>) list.get(i);
					mapConvertXml(hm, sb);
				}
				sb.append("</" + key + ">");
			} else {
				if (value instanceof HashMap) {
					sb.append("<" + key + ">");
					mapConvertXml((HashMap) value, sb);
					sb.append("</" + key + ">");
				} else {
					sb.append("<" + key + ">" + value + "</" + key + ">");
				}
			}
		}
	}

	@SuppressWarnings("unchecked")
	public static Object xmlMap(String xmlText){
		Document doc = null;
		try {
			doc = DocumentHelper.parseText(xmlText);
			Map<String, Object> map = (Map<String, Object>) xml2map(doc.getRootElement());
			return map;
		} catch (DocumentException e) {
			e.printStackTrace();
		}
		return null;
	}
	@SuppressWarnings("unchecked")
	private static Object xml2map(Element element) {
		Map<String, Object> map = new HashMap<String, Object>();
		List<Element> elements = element.elements();
		if (elements.size() == 0) {
			map.put(element.getName(), element.getText());
			if (!element.isRootElement()) {
				return element.getText();
			}
		} else if (elements.size() == 1) {
			map.put(elements.get(0).getName(), xml2map(elements.get(0)));
		} else if (elements.size() > 1) {
			Map<String, Element> tempMap = new HashMap<String, Element>();
			for (Element ele : elements) {
				tempMap.put(ele.getName(), ele);
			}
			Set<String> keySet = tempMap.keySet();
			for (String string : keySet) {
				Namespace namespace = tempMap.get(string).getNamespace();
				List<Element> elements2 = element.elements(new QName(string, namespace));
				if (elements2.size() > 1) {
					List<Object> list = new ArrayList<Object>();
					for (Element ele : elements2) {
						list.add(xml2map(ele));
					}
					map.put(string, list);
				} else {
					map.put(string, xml2map(elements2.get(0)));
				}
			}
		}
		return map;
	}
	

	public static void main(String[] args) {
		Map xmlMap = new HashMap();
		Map<String, Object> dataMap = new HashMap<String, Object>();
		Map<String, Object> bodyMap = new HashMap<String, Object>();
		bodyMap.put("orgTranFlow", "CF300003751320170612094236992465");
		Map<String, String> childrenMap = new HashMap<String, String>();
		childrenMap.put("version", "version");
		childrenMap.put("msgtype", "0001");
		childrenMap.put("channelno", "99");
		childrenMap.put("merchantno", "CF3000037513");
		dataMap.put("head", childrenMap);
		dataMap.put("body", bodyMap);
		xmlMap.put("data", dataMap);
		String bytes = mapToXml(xmlMap);
		System.out.println(bytes);
	}
}
